from flask import request
from flask_restx import Namespace, fields, Resource

from lib.CVEs import CveHandler
from lib.DatabaseLayer import cvesForCPE
from lib.Query import qcvesForCPE
from web.restapi.cpe_convert import message

api = Namespace("cve", description="Endpoints for requesting cve information", path="/")

access_entry = api.model(
    "access",
    {
        "authentication": fields.String(
            description="This metric describes the level of privileges an attacker must possess before successfully "
            "exploiting the vulnerability.",
            example="SINGLE",
        ),
        "complexity": fields.String(
            description="The Attack Complexity metric describes the conditions beyond the attacker's control that must "
            "exist in order to exploit the vulnerability. As described below, such conditions may require "
            "the collection of more information about the target, the presence of certain system "
            "configuration settings, or computational exceptions.",
            example="LOW",
        ),
        "vector": fields.String(
            description="This metric reflects the context by which vulnerability exploitation is possible. This metric "
            "value (and consequently the Base score) will be larger the more remote (logically, "
            "and physically) an attacker can be in order to exploit the vulnerable component.",
            example="NETWORK",
        ),
    },
)

access_V3_entry = api.model(
    "access_V3",
    {
        "attackvector": fields.String(
            description="This metric reflects the context by which vulnerability exploitation is possible. This metric "
            "value (and consequently the Base Score) will be larger the more remote (logically, "
            "and physically) an attacker can be in order to exploit the vulnerable component. The "
            "assumption is that the number of potential attackers for a vulnerability that could be "
            "exploited from across a network is larger than the number of potential attackers that could "
            "exploit a vulnerability requiring physical access to a device, and therefore warrants a "
            "greater Base Score.",
            example="NETWORK",
        ),
        "attackcomplexity": fields.String(
            description="This metric describes the conditions beyond the attacker’s control that must exist in order "
            "to exploit the vulnerability. As described below, such conditions may require the collection "
            "of more information about the target, or computational exceptions. Importantly, the "
            "assessment of this metric excludes any requirements for user interaction in order to exploit "
            "the vulnerability (such conditions are captured in the User Interaction metric). If a "
            "specific configuration is required for an attack to succeed, the Base metrics should be "
            "scored assuming the vulnerable component is in that configuration. The Base Score is greatest "
            "for the least complex attacks.",
            example="LOW",
        ),
        "privilegesrequired": fields.String(
            description="This metric describes the level of privileges an attacker must possess before successfully "
            "exploiting the vulnerability. The Base Score is greatest if no privileges are required.",
            example="NONE",
        ),
        "userinteraction": fields.String(
            description="This metric captures the requirement for a human user, other than the attacker, to "
            "participate in the successful compromise of the vulnerable component. This metric determines whether the "
            "vulnerability can be exploited solely at the will of the attacker, or whether a separate user "
            "(or user-initiated process) must participate in some manner. The Base Score is greatest when "
            "no user interaction is required.",
            example="REQUIRED",
        ),
        "scope": fields.String(
            description="The Scope metric captures whether a vulnerability in one vulnerable component impacts "
            "resources in components beyond its security scope. Formally, a security authority is a "
            "mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that "
            "defines and enforces access control in terms of how certain subjects/actors (e.g., human "
            "users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) "
            "in a controlled manner. All the subjects and objects under the jurisdiction of a single "
            "security authority are considered to be under one security scope. If a vulnerability in a "
            "vulnerable component can affect a component which is in a different security scope than the "
            "vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a "
            "vulnerability breaches a security/trust boundary and impacts components outside the security "
            "scope in which vulnerable component resides, a Scope change occurs. The security scope of a "
            "component encompasses other components that provide functionality solely to that component, "
            "even if these other components have their own security authority. For example, a database "
            "used solely by one application is considered part of that application’s security scope even "
            "if the database has its own security authority, e.g., a mechanism controlling access to "
            "database records based on database users and associated database privileges. The Base Score "
            "is greatest when a scope change occurs.",
            example="CHANGED",
        ),
    },
)

impact_entry = api.model(
    "Impact",
    {
        "availability": fields.String(
            description="This metric measures the impact to the availability of the impacted component resulting "
            "from a successfully exploited vulnerability. While the Confidentiality and Integrity impact "
            "metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) "
            "used by the impacted component, this metric refers to the loss of availability of the "
            "impacted component itself, such as a networked service (e.g., web, database, email). Since "
            "availability refers to the accessibility of information resources, attacks that consume "
            "network bandwidth, processor cycles, or disk space all impact the availability of an impacted "
            "component.",
            example="COMPLETE",
        ),
        "confidentiality": fields.String(
            description="This metric measures the impact to the confidentiality of the information resources managed "
            "by a software component due to a successfully exploited vulnerability. Confidentiality refers "
            "to limiting information access and disclosure to only authorized users, as well as preventing "
            "access by, or disclosure to, unauthorized ones.",
            example="COMPLETE",
        ),
        "integrity": fields.String(
            description="This metric measures the impact to integrity of a successfully exploited vulnerability. "
            "Integrity refers to the trustworthiness and veracity of information.",
            example="COMPLETE",
        ),
    },
)

impact_V3_entry = api.model(
    "Impact",
    {
        "availability": fields.String(
            description="This metric measures the impact to the availability of the impacted component resulting "
            "from a successfully exploited vulnerability. While the Confidentiality and Integrity impact "
            "metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) "
            "used by the impacted component, this metric refers to the loss of availability of the "
            "impacted component itself, such as a networked service (e.g., web, database, email). Since "
            "availability refers to the accessibility of information resources, attacks that consume "
            "network bandwidth, processor cycles, or disk space all impact the availability of an impacted "
            "component.",
            example="HIGH",
        ),
        "confidentiality": fields.String(
            description="This metric measures the impact to the confidentiality of the information resources managed "
            "by a software component due to a successfully exploited vulnerability. Confidentiality refers "
            "to limiting information access and disclosure to only authorized users, as well as preventing "
            "access by, or disclosure to, unauthorized ones.",
            example="HIGH",
        ),
        "integrity": fields.String(
            description="This metric measures the impact to integrity of a successfully exploited vulnerability. "
            "Integrity refers to the trustworthiness and veracity of information.",
            example="HIGH",
        ),
    },
)

tax_inner = api.model(
    "TaxonomyInner",
    {
        "Entry_ID": fields.String(description="Taxonomy entry id", example="1499.001",),
        "Entry_Name": fields.String(
            description="Taxonomy name",
            example="Endpoint Denial of Service:OS Exhaustion Flood",
        ),
        "URL": fields.String(
            description="Taxonomy URL",
            example="https://attack.mitre.org/techniques/T1499/001",
        ),
    },
)

tax_wild = fields.Wildcard(
    fields.Nested(tax_inner), description="Taxonomy mapping id", skip_none=True,
)

taxonomy_entry = api.model("documents", {"*": tax_wild})

taxonomy = api.model(
    "Taxonomy",
    {
        "ATTACK": fields.Nested(
            taxonomy_entry,
            skip_none=True,
            description="Mitre Att&ck taxonomy",
            example={
                "1499_001": {
                    "Entry_ID": "1499.001",
                    "Entry_Name": "Endpoint Denial of Service:OS Exhaustion Flood",
                    "URL": "https://attack.mitre.org/techniques/T1499/001",
                },
                "1499_004": {
                    "Entry_ID": "1499.004",
                    "Entry_Name": "Endpoint Denial of Service:Application or System Exploitation",
                    "URL": "https://attack.mitre.org/techniques/T1499/004",
                },
            },
        ),
    },
)

execution_inner = api.model(
    "ExecutionInner",
    {
        "Phase": fields.String(description="Execution phase", example="Explore"),
        "Description": fields.String(
            description="Execution phase description",
            example="[Determine application's/system's password policy] Determine the password policies of the target "
            "application/system.",
        ),
        "Techniques": fields.List(
            fields.String,
            description="A list of used techniques during the phase",
            example=[
                "Determine minimum and maximum allowed password lengths.",
                "Determine format of allowed passwords (whether they are required or allowed to contain numbers, "
                "special characters, etc.).",
                "Determine account lockout policy (a strict account lockout policy will prevent brute force attacks).",
            ],
        ),
    },
)

execution_wild = fields.Wildcard(
    fields.Nested(execution_inner),
    description="Execution phase mapping id",
    skip_none=True,
)

execution_entry = api.model("documents", {"*": execution_wild})

capec_entry = api.model(
    "Capec_entry",
    {
        "id": fields.String(description="ID number of the CAPEC", example="242",),
        "name": fields.String(
            description="Name of the CAPEC", example="Code Injection",
        ),
        "prerequisites": fields.String(
            description="Prerequisites of the CAPEC",
            example="The target software does not validate user-controlled input such that the execution of a process "
            "may be altered by sending code in through legitimate data channels, using no other mechanism.",
        ),
        "related_weakness": fields.List(
            fields.String,
            description="List with related CWE numbers",
            example=["94", "270", "271"],
        ),
        "related_capecs": fields.List(
            fields.String,
            description="List with related CAPEC numbers",
            example=["112", "151", "560", "600", "653"],
        ),
        "solutions": fields.String(
            description="Solutions for mitigating the CAPEC",
            example="Utilize strict type, character, and encoding enforcement Ensure all input content that is "
            "delivered to client is sanitized against an acceptable content specification. Perform input "
            "validation for all content. Enforce regular patching of software.",
        ),
        "summary": fields.String(
            description="Summary of the CAPEC",
            example="An adversary exploits a weakness in input validation on the target to inject new code into that "
            "which is currently executing. This differs from code inclusion in that code inclusion involves "
            "the addition or replacement of a reference to a code file, which is subsequently loaded by the "
            "target and used as part of the code of some application.",
        ),
        "loa": fields.String(description="Likelyhood of attack", example="Medium",),
        "typical_severity": fields.String(
            description="Typical severity", example="High",
        ),
        "taxonomy": fields.Nested(
            taxonomy,
            skip_none=True,
            description="Taxonomy linked to this CAPEC",
            example={
                "ATTACK": {
                    "1499_001": {
                        "Entry_ID": "1499.001",
                        "Entry_Name": "Endpoint Denial of Service:OS Exhaustion Flood",
                        "URL": "https://attack.mitre.org/techniques/T1499/001",
                    },
                    "1499_004": {
                        "Entry_ID": "1499.004",
                        "Entry_Name": "Endpoint Denial of Service:Application or System Exploitation",
                        "URL": "https://attack.mitre.org/techniques/T1499/004",
                    },
                }
            },
        ),
        "execution_flow": fields.Nested(
            execution_entry,
            skip_none=True,
            description="Phased description of attack execution flow",
            example={
                "1": {
                    "Phase": "Explore",
                    "Description": "[Determine application's/system's password policy] Determine the password policies "
                    "of the target application/system.",
                    "Techniques": [
                        "Determine minimum and maximum allowed password lengths.",
                        "Determine format of allowed passwords (whether they are required or allowed to contain "
                        "numbers, special characters, etc.).",
                        "Determine account lockout policy (a strict account lockout policy will prevent brute "
                        "force attacks).",
                    ],
                },
                "2": {
                    "Phase": "Exploit",
                    "Description": "[Brute force password] Given the finite space of possible passwords dictated by "
                    "the password policy determined in the previous step, try all possible passwords "
                    "for a known user ID until application/system grants access.",
                    "Techniques": [
                        "Manually or automatically enter all possible passwords through the application/system's "
                        "interface. In most systems, start with the shortest and simplest possible passwords, because "
                        "most users tend to select such passwords if allowed to do so.",
                        "Perform an offline dictionary attack or a rainbow table attack against a known password hash.",
                    ],
                },
            },
        ),
    },
)

refmap_inner = fields.List(
    fields.String,
    description="Reference mappings",
    example=["https://pastebin.com/QTev1TjM"],
)

refmap_wild = fields.Wildcard(refmap_inner, description="Reference mapping id")

refmap = api.model("documents", {"*": refmap_wild})

vuln_conf = api.model(
    "VulnConf",
    {
        "id": fields.String(
            description="ID of the vulnerable configuration",
            example="cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
        ),
        "title": fields.String(
            description="Title of the vulnerable configuration",
            example="cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
        ),
    },
)

contributors = api.model(
    "Contributors",
    {
        "name": fields.String(
            description="Contributor name", example="Dragos Prisaca",
        ),
        "organization": fields.String(
            description="Organization name", example="Symantec Corporation",
        ),
    },
)

def_extensions = api.model(
    "DefExtensions",
    {
        "comment": fields.String(
            description="Comment",
            example="Microsoft Windows Vista (32-bit) Service Pack 1 is installed",
        ),
        "oval": fields.String(
            description="Oval reference", example="oval:org.mitre.oval:def:4873"
        ),
    },
)

oval_entry = api.model(
    "OvalEntry",
    {
        "accepted": fields.DateTime(
            description="Oval Date Time", example="2014-06-16T04:00:06.077-04:00",
        ),
        "class": fields.String(description="Oval class", example="vulnerability",),
        "contributors": fields.List(
            fields.Nested(contributors),
            skip_none=True,
            description="List with contributors",
            example=[
                {"name": "Dragos Prisaca", "organization": "Symantec Corporation"},
                {"name": "Chandan S", "organization": "SecPod Technologies"},
                {"name": "Maria Kedovskaya", "organization": "ALTX-SOFT"},
                {"name": "Maria Mikhno", "organization": "ALTX-SOFT"},
            ],
        ),
        "definition_extensions": fields.List(
            fields.Nested(def_extensions),
            skip_none=True,
            description="List with Definition extensions",
            example=[
                {
                    "comment": "Microsoft Windows Vista (32-bit) Service Pack 1 is installed",
                    "oval": "oval:org.mitre.oval:def:4873",
                },
                {
                    "comment": "Microsoft Windows Vista x64 Edition Service Pack 1 is installed",
                    "oval": "oval:org.mitre.oval:def:5254",
                },
                {
                    "comment": "Microsoft Windows Vista (32-bit) Service Pack 2 is installed",
                    "oval": "oval:org.mitre.oval:def:6124",
                },
                {
                    "comment": "Microsoft Windows Vista x64 Edition Service Pack 2 is installed",
                    "oval": "oval:org.mitre.oval:def:5594",
                },
                {
                    "comment": "Microsoft Windows 7 (32-bit) is installed",
                    "oval": "oval:org.mitre.oval:def:6165",
                },
                {
                    "comment": "Microsoft Windows 7 x64 Edition is installed",
                    "oval": "oval:org.mitre.oval:def:5950",
                },
                {
                    "comment": "Microsoft Windows 7 (32-bit) Service Pack 1 is installed",
                    "oval": "oval:org.mitre.oval:def:12292",
                },
                {
                    "comment": "Microsoft Windows 7 x64 Service Pack 1 is installed",
                    "oval": "oval:org.mitre.oval:def:12627",
                },
            ],
        ),
        "description": fields.String(
            description="Oval description",
            example="The Bluetooth Stack 2.1 in Microsoft Windows Vista SP1 and SP2 and Windows 7 Gold and SP1 does "
            "not prevent access to objects in memory that (1) were not properly initialized or (2) have "
            "been deleted, which allows remote attackers to execute arbitrary code via crafted Bluetooth "
            "packets, aka 'Bluetooth Stack Vulnerability'.",
        ),
        "family": fields.String(description="Oval family", example="windows"),
        "id": fields.String(
            description="Oval id", example="oval:org.mitre.oval:def:12094"
        ),
        "status": fields.String(description="Oval status", example="accepted"),
        "submitted": fields.DateTime(
            description="Oval submitted", example="2011-07-12T13:00:00"
        ),
        "title": fields.String(
            description="Oval title", example="Bluetooth Stack Vulnerability"
        ),
        "version": fields.String(description="Oval version", example="52"),
    },
)

MsBulletin = api.model(
    "MsBulletin",
    {
        "bulletin_id": fields.String(
            description="MSBulletin id number", example="MS11-053"
        ),
        "bulletin_url": fields.String(
            description="MSBulletin url",
            example="https://www.windows.com/some_url_to_ms_bulletin",
        ),
        "date": fields.DateTime(
            description="MSBulletin date", example="2011-07-12T00:00:00"
        ),
        "impact": fields.String(
            description="MSBulletin impact", example="Remote Code Execution"
        ),
        "knowledgebase_id": fields.String(
            description="MSBulletin knowledgebase_id", example="2566220"
        ),
        "knowledgebase_url": fields.String(
            description="MSBulletin knowledgebase_url",
            example="https://www.windows.com/some_url_to_ms_bulletin_knowledge_base",
        ),
        "severity": fields.String(
            description="MSBulletin severity level", example="Critical"
        ),
        "title": fields.String(
            description="MSBulletin title",
            example="Vulnerability in Bluetooth Stack Could Allow Remote Code Execution",
        ),
    },
)

statements = api.model(
    "Statements",
    {
        "contributor": fields.String(
            description="Statement contributor", example="Tomas Hoger",
        ),
        "lastmodified": fields.Date(
            description="Statement date", example="2009-09-02",
        ),
        "organization": fields.String(
            description="Statement organization", example="Red Hat",
        ),
        "statement": fields.String(
            description="Statement",
            example="This issue did not affect the versions of Linux kernel as shipped with Red Hat Enterprise Linux "
            "2.1, 3, 4, and Red Hat Enterprise MRG. This issue was addressed in Red Hat Enterprise Linux 5 "
            "by https://rhn.redhat.com/errata/RHSA-2009-1243.html",
        ),
    },
)

redhat_inner = api.model(
    "RHInner",
    {
        "id": fields.String(
            description="Red Hat Security Advisory id", example="RHSA-2009:1243"
        )
    },
)

redhat_wild = fields.Wildcard(
    fields.Nested(redhat_inner), description="Red Hat mapping id", skip_none=True,
)

redhat = api.model("documents", {"*": redhat_wild})

redhat_entry = api.model(
    "RedHatEntry",
    {
        "rpms": fields.List(
            fields.String,
            description="List with affected packages",
            example=[
                "kernel-0:2.6.18-164.el5",
                "kernel-PAE-0:2.6.18-164.el5",
                "kernel-PAE-debuginfo-0:2.6.18-164.el5",
                "kernel-PAE-devel-0:2.6.18-164.el5",
                "kernel-debug-0:2.6.18-164.el5",
                "kernel-debug-debuginfo-0:2.6.18-164.el5",
                "kernel-debug-devel-0:2.6.18-164.el5",
                "kernel-debuginfo-0:2.6.18-164.el5",
                "kernel-debuginfo-common-0:2.6.18-164.el5",
                "kernel-devel-0:2.6.18-164.el5",
                "kernel-doc-0:2.6.18-164.el5",
                "kernel-headers-0:2.6.18-164.el5",
                "kernel-kdump-0:2.6.18-164.el5",
                "kernel-kdump-debuginfo-0:2.6.18-164.el5",
                "kernel-kdump-devel-0:2.6.18-164.el5",
                "kernel-xen-0:2.6.18-164.el5",
                "kernel-xen-debuginfo-0:2.6.18-164.el5",
                "kernel-xen-devel-0:2.6.18-164.el5",
            ],
        ),
        "advisories": fields.List(
            fields.Nested(redhat),
            skip_none=True,
            description="List with advisories",
            example=[{"rhsa": {"id": "RHSA-2009:1243"}}],
        ),
    },
)

cve_entry_base = api.model(
    "CVE_Entry_Base",
    {
        "Modified": fields.DateTime(
            description="Modified date time", example="2020-10-07T15:01:00",
        ),
        "Published": fields.DateTime(
            description="Published date time", example="2020-09-24T15:15:00",
        ),
        "access": fields.Nested(
            access_entry,
            skip_none=True,
            description="Access vectors",
            example={
                "authentication": "SINGLE",
                "complexity": "LOW",
                "vector": "NETWORK",
            },
        ),
        "assigner": fields.String(
            description="Assigner of the CVE", example="cve@mitre.org",
        ),
        "capec": fields.List(
            fields.Nested(capec_entry),
            skip_none=True,
            description="CAPEC's related to the CVE",
            example=[
                {
                    "id": "49",
                    "name": "Password Brute Forcing",
                    "prerequisites": "An adversary needs to know a username to target. The system uses password based "
                    "authentication as the one factor authentication mechanism. An application does "
                    "not have a password throttling mechanism in place. A good password throttling "
                    "mechanism will make it almost impossible computationally to brute force a "
                    "password as it may either lock out the user after a certain number of incorrect "
                    "attempts or introduce time out periods. Both of these would make a brute force "
                    "attack impractical.",
                    "related_weakness": [
                        "257",
                        "262",
                        "263",
                        "307",
                        "308",
                        "309",
                        "521",
                        "654",
                    ],
                    "related_capecs": ["112", "151", "560", "600", "653"],
                    "solutions": "Implement a password throttling mechanism. This mechanism should take into account "
                    "both the IP address and the log in name of the user. Put together a strong password "
                    "policy and make sure that all user created passwords comply with it. Alternatively "
                    "automatically generate strong passwords for users. Passwords need to be recycled to "
                    "prevent aging, that is every once in a while a new password must be chosen.",
                    "summary": "In this attack, the adversary tries every possible value for a password until they "
                    "succeed. A brute force attack, if feasible computationally, will always be successful "
                    "because it will essentially go through all possible passwords given the alphabet "
                    "used (lower case letters, upper case letters, numbers, symbols, etc.) and the maximum "
                    "length of the password. A system will be particularly vulnerable to this type of an "
                    "attack if it does not have a proper enforcement mechanism in place to ensure that "
                    "passwords selected by users are strong passwords that comply with an adequate password "
                    "policy. In practice a pure brute force attack on passwords is rarely used, unless the "
                    "password is suspected to be weak. Other password cracking methods exist that are far "
                    "more effective (e.g. dictionary attacks, rainbow tables, etc.). Knowing the password "
                    "policy on the system can make a brute force attack more efficient. For instance, if "
                    "the policy states that all passwords must be of a certain level, there is no need to "
                    "check smaller candidates.",
                    "loa": "Medium",
                    "typical_severity": "High",
                    "taxonomy": {
                        "ATTACK": {
                            "1110_001": {
                                "Entry_ID": "1110.001",
                                "Entry_Name": "Brute Force:Password Guessing",
                                "URL": "https://attack.mitre.org/techniques/T1110/001",
                            }
                        }
                    },
                    "execution_flow": {
                        "2": {
                            "Phase": "Exploit",
                            "Description": "[Brute force password] Given the finite space of possible passwords "
                            "dictated by the password policy determined in the previous step, try all "
                            "possible passwords for a known user ID until application/system grants "
                            "access.",
                            "Techniques": [
                                "Manually or automatically enter all possible passwords through the "
                                "application/system's interface. In most systems, start with the shortest and simplest "
                                "possible passwords, because most users tend to select such passwords if allowed to "
                                "do so.",
                                "Perform an offline dictionary attack or a rainbow table attack against a known "
                                "password hash.",
                            ],
                        },
                        "1": {
                            "Phase": "Explore",
                            "Description": "[Determine application's/system's password policy] Determine the password "
                            "policies of the target application/system.",
                            "Techniques": [
                                "Determine minimum and maximum allowed password lengths.",
                                "Determine format of allowed passwords (whether they are required or allowed to "
                                "contain numbers, special characters, etc.).",
                                "Determine account lockout policy (a strict account lockout policy will prevent brute "
                                "force attacks).",
                            ],
                        },
                    },
                },
                {
                    "id": "35",
                    "name": "Leverage Executable Code in Non-Executable Files",
                    "prerequisites": "The attacker must have the ability to modify non-executable files consumed by "
                    "the target software.",
                    "related_weakness": [
                        "264",
                        "270",
                        "272",
                        "275",
                        "282",
                        "59",
                        "714",
                        "94",
                        "95",
                        "96",
                        "97",
                    ],
                    "related_capecs": ["112", "151", "560", "600", "653"],
                    "solutions": "Design: Enforce principle of least privilege Design: Run server interfaces with a "
                    "non-root account and/or utilize chroot jails or other configuration techniques to "
                    "constrain privileges even if attacker gains some limited access to commands. "
                    "Implementation: Perform testing such as pen-testing and vulnerability scanning to "
                    "identify directories, programs, and interfaces that grant direct access to "
                    "executables. Implementation: Implement host integrity monitoring to detect any "
                    "unwanted altering of configuration files. Implementation: Ensure that files that "
                    "are not required to execute, such as configuration files, are not over-privileged, "
                    "i.e. not allowed to execute.",
                    "summary": "An attack of this type exploits a system's trust in configuration and resource files. "
                    "When the executable loads the resource (such as an image file or configuration file) "
                    "the attacker has modified the file to either execute malicious code directly or "
                    "manipulate the target process (e.g. application server) to execute based on the "
                    "malicious configuration parameters. Since systems are increasingly interrelated "
                    "mashing up resources from local and remote sources the possibility of this attack "
                    "occurring is high.",
                },
                {
                    "id": "77",
                    "name": "Manipulating User-Controlled Variables",
                    "prerequisites": "A variable consumed by the application server is exposed to the client. A "
                    "variable consumed by the application server can be overwritten by the user. "
                    "The application server trusts user supplied data to compute business logic. "
                    "The application server does not perform proper input validation.",
                    "related_weakness": ["15", "285", "302", "473", "94", "96"],
                    "solutions": "If the register_globals option is enabled, PHP will create global variables for "
                    "each GET, POST, and cookie variable included in the HTTP request. This means that a "
                    "malicious user may be able to set variables unexpectedly. For instance make sure "
                    "that the server setting for PHP does not expose global variables. A software system "
                    "should be reluctant to trust variables that have been initialized outside of its "
                    "trust boundary. Ensure adequate checking is performed when relying on input from "
                    "outside a trust boundary. Separate the presentation layer and the business logic "
                    "layer. Variables at the business logic layer should not be exposed at the "
                    "presentation layer. This is to prevent computation of business logic from user "
                    "controlled input data. Use encapsulation when declaring your variables. This is to "
                    "lower the exposure of your variables. Assume all input is malicious. Create a white "
                    "list that defines all valid input to the software system based on the requirements "
                    "specifications. Input that does not match against the white list should be rejected "
                    "by the program.",
                    "summary": "This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). "
                    "An attacker can override environment variables leveraging user-supplied, untrusted "
                    "query variables directly used on the application server without any data sanitization. "
                    "In extreme cases, the attacker can change variables controlling the business logic of "
                    "the application. For instance, in languages like PHP, a number of poorly set default "
                    "configurations may allow the user to override variables.",
                },
            ],
        ),
        "cvss": fields.Float(description="CVSS score", example=9.0,),
        "impactScore": fields.Float(description="CVSS impact score", example=9.6,),
        "exploitabilityScore": fields.Float(
            description="CVSS exploitability score", example=9.6,
        ),
        "cvss-time": fields.DateTime(
            description="Time when the CVSS was established",
            example="2020-10-07T15:01:00",
        ),
        "cvss-vector": fields.String(
            description="CVSS Vector string", example="AV:N/AC:L/Au:S/C:C/I:C/A:C"
        ),
        "cwe": fields.String(
            description="CWE number to which this CVE belongs to", example="CWE-94"
        ),
        "id": fields.String(
            description="ID number of the CVE", example="CVE-2020-24365",
        ),
        "impact": fields.Nested(
            impact_entry,
            skip_none=True,
            description="Impact vectors",
            example={
                "availability": "COMPLETE",
                "confidentiality": "COMPLETE",
                "integrity": "COMPLETE",
            },
        ),
        "impact3": fields.Nested(
            impact_V3_entry,
            skip_none=True,
            description="CvssV3 impact vectors",
            example={
                "availability": "HIGH",
                "confidentiality": "HIGH",
                "integrity": "HIGH",
            },
        ),
        "exploitability3": fields.Nested(
            access_V3_entry,
            skip_none=True,
            description="CvssV3 access vectors",
            example={
                "attackvector": "NETWORK",
                "attackcomplexity": "LOW",
                "privilegesrequired": "NONE",
                "userinteraction": "REQUIRED",
                "scope": "CHANGED",
            },
        ),
        "cvss3": fields.Float(description="CvssV3 score", example=9.6,),
        "impactScore3": fields.Float(description="CvssV3 impact score", example=9.6,),
        "exploitabilityScore3": fields.Float(
            description="CvssV3 exploitability score", example=9.6,
        ),
        "cvss3-vector": fields.String(
            description="CvssV3 Vector string",
            example="CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
        ),
        "last-modified": fields.DateTime(
            description="Last modified date time", example="2020-10-07T15:01:00"
        ),
        "references": fields.List(
            fields.String,
            description="CVE references",
            example=["https://pastebin.com/QTev1TjM"],
        ),
        "summary": fields.String(
            description="CVE Summary",
            example="An issue was discovered on Gemtek WRTM-127ACN 01.01.02.141 and WRTM-127x9 01.01.02.127 devices. "
            "The Monitor Diagnostic network page allows an authenticated attacker to execute a command directly "
            "on the target machine. Commands are executed as the root user (uid 0). (Even if a login is "
            "required, most routers are left with default credentials.)",
        ),
    },
)

cve_entry = api.inherit(
    "CVE_Entry_Full",
    cve_entry_base,
    {
        "refmap": fields.Nested(
            refmap,
            skip_none=True,
            description="CVE Reference mapping",
            example={"misc": ["https://pastebin.com/QTev1TjM"]},
        ),
        "vulnerable_configuration": fields.List(
            fields.Nested(vuln_conf),
            skip_none=True,
            description="Vulnerable configurations CPE's",
            example=[
                {
                    "id": "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:h:gemteks:wrtm-127acn:-:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:h:gemteks:wrtm-127acn:-:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:h:gemteks:wrtm-127x9:-:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:h:gemteks:wrtm-127x9:-:*:*:*:*:*:*:*",
                },
            ],
        ),
        "vulnerable_configuration_cpe_2_2": fields.List(
            fields.Nested(vuln_conf),
            skip_none=True,
            description="Vulnerable configurations CPE's",
            example=[
                {
                    "id": "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:h:gemteks:wrtm-127acn:-:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:h:gemteks:wrtm-127acn:-:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
                },
                {
                    "id": "cpe:2.3:h:gemteks:wrtm-127x9:-:*:*:*:*:*:*:*",
                    "title": "cpe:2.3:h:gemteks:wrtm-127x9:-:*:*:*:*:*:*:*",
                },
            ],
        ),
        "vulnerable_product": fields.List(
            fields.String,
            description="Vulnerable products CPE's",
            example=[
                "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
            ],
        ),
        "oval": fields.List(
            fields.Nested(oval_entry),
            skip_none=True,
            description="List with Oval entries",
            example=[
                {
                    "accepted": "2014-06-16T04:00:06.077-04:00",
                    "class": "vulnerability",
                    "contributors": [
                        {
                            "name": "Dragos Prisaca",
                            "organization": "Symantec Corporation",
                        },
                        {"name": "Chandan S", "organization": "SecPod Technologies"},
                        {"name": "Maria Kedovskaya", "organization": "ALTX-SOFT"},
                        {"name": "Maria Mikhno", "organization": "ALTX-SOFT"},
                    ],
                    "definition_extensions": [
                        {
                            "comment": "Microsoft Windows Vista (32-bit) Service Pack 1 is installed",
                            "oval": "oval:org.mitre.oval:def:4873",
                        },
                        {
                            "comment": "Microsoft Windows Vista x64 Edition Service Pack 1 is installed",
                            "oval": "oval:org.mitre.oval:def:5254",
                        },
                        {
                            "comment": "Microsoft Windows Vista (32-bit) Service Pack 2 is installed",
                            "oval": "oval:org.mitre.oval:def:6124",
                        },
                        {
                            "comment": "Microsoft Windows Vista x64 Edition Service Pack 2 is installed",
                            "oval": "oval:org.mitre.oval:def:5594",
                        },
                        {
                            "comment": "Microsoft Windows 7 (32-bit) is installed",
                            "oval": "oval:org.mitre.oval:def:6165",
                        },
                        {
                            "comment": "Microsoft Windows 7 x64 Edition is installed",
                            "oval": "oval:org.mitre.oval:def:5950",
                        },
                        {
                            "comment": "Microsoft Windows 7 (32-bit) Service Pack 1 is installed",
                            "oval": "oval:org.mitre.oval:def:12292",
                        },
                        {
                            "comment": "Microsoft Windows 7 x64 Service Pack 1 is installed",
                            "oval": "oval:org.mitre.oval:def:12627",
                        },
                    ],
                    "description": "The Bluetooth Stack 2.1 in Microsoft Windows Vista SP1 and SP2 and Windows 7 Gold "
                    "and SP1 does not prevent access to objects in memory that (1) were not properly "
                    "initialized or (2) have been deleted, which allows remote attackers to execute "
                    'arbitrary code via crafted Bluetooth packets, aka "Bluetooth Stack Vulnerability."',
                    "family": "windows",
                    "id": "oval:org.mitre.oval:def:12094",
                    "status": "accepted",
                    "submitted": "2011-07-12T13:00:00",
                    "title": "Bluetooth Stack Vulnerability",
                    "version": "52",
                }
            ],
        ),
        "msbulletin": fields.List(
            fields.Nested(MsBulletin),
            skip_none=True,
            description="List with msbulletins",
            example=[
                {
                    "bulletin_id": "MS11-053",
                    "bulletin_url": "null",
                    "date": "2011-07-12T00:00:00",
                    "impact": "Remote Code Execution",
                    "knowledgebase_id": "2566220",
                    "knowledgebase_url": "null",
                    "severity": "Critical",
                    "title": "Vulnerability in Bluetooth Stack Could Allow Remote Code Execution",
                }
            ],
        ),
        "statements": fields.List(
            fields.Nested(statements),
            skip_none=True,
            description="List with statements",
            example=[
                {
                    "contributor": "Tomas Hoger",
                    "lastmodified": "2009-09-02",
                    "organization": "Red Hat",
                    "statement": "This issue did not affect the versions of Linux kernel as shipped with Red Hat "
                    "Enterprise Linux 2.1, 3, 4, and Red Hat Enterprise MRG. This issue was addressed "
                    "in Red Hat Enterprise Linux 5 by https://rhn.redhat.com/errata/RHSA-2009-1243.html",
                }
            ],
        ),
        "redhat": fields.Nested(
            redhat_entry,
            skip_none=True,
            description="Redhat Security advisories",
            example={
                "advisories": [{"rhsa": {"id": "RHSA-2009:1243"}}],
                "rpms": [
                    "kernel-0:2.6.18-164.el5",
                    "kernel-PAE-0:2.6.18-164.el5",
                    "kernel-PAE-debuginfo-0:2.6.18-164.el5",
                    "kernel-PAE-devel-0:2.6.18-164.el5",
                    "kernel-debug-0:2.6.18-164.el5",
                    "kernel-debug-debuginfo-0:2.6.18-164.el5",
                    "kernel-debug-devel-0:2.6.18-164.el5",
                    "kernel-debuginfo-0:2.6.18-164.el5",
                    "kernel-debuginfo-common-0:2.6.18-164.el5",
                    "kernel-devel-0:2.6.18-164.el5",
                    "kernel-doc-0:2.6.18-164.el5",
                    "kernel-headers-0:2.6.18-164.el5",
                    "kernel-kdump-0:2.6.18-164.el5",
                    "kernel-kdump-debuginfo-0:2.6.18-164.el5",
                    "kernel-kdump-devel-0:2.6.18-164.el5",
                    "kernel-xen-0:2.6.18-164.el5",
                    "kernel-xen-debuginfo-0:2.6.18-164.el5",
                    "kernel-xen-devel-0:2.6.18-164.el5",
                ],
            },
        ),
    },
)

cve_last_entries = api.inherit(
    "CVE_Entry_last",
    cve_entry_base,
    {
        "vulnerable_configuration": fields.List(
            fields.String,
            description="Vulnerable configurations CPE's",
            example=[
                "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
            ],
        ),
        "vulnerable_configuration_cpe_2_2": fields.List(
            fields.String,
            description="Vulnerable configurations CPE's",
            example=[
                "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
            ],
        ),
        "vulnerable_product": fields.List(
            fields.String,
            description="Vulnerable products CPE's",
            example=[
                "cpe:2.3:o:gemteks:wrtm-127acn_firmware:01.01.02.141:*:*:*:*:*:*:*",
                "cpe:2.3:o:gemteks:wrtm-127x9_firmware:01.01.02.127:*:*:*:*:*:*:*",
            ],
        ),
    },
)

search_entries = api.model(
    "SearchEntries",
    {
        "results": fields.List(
            fields.Nested(cve_last_entries),
            description="CVE results",
            example=[
                {
                    "Modified": "2018-10-12T21:29:00",
                    "Published": "1999-05-07T04:00:00",
                    "access": {
                        "authentication": "NONE",
                        "complexity": "HIGH",
                        "vector": "NETWORK",
                    },
                    "assigner": "cve@mitre.org",
                    "cvss": 2.6,
                    "impactScore": 3.0,
                    "exploitabilityScore": 3.0,
                    "cvss-time": "2018-10-12T21:29:00",
                    "cvss-vector": "AV:N/AC:H/Au:N/C:N/I:P/A:N",
                    "cwe": "NVD-CWE-Other",
                    "id": "CVE-1999-0717",
                    "impact": {
                        "availability": "NONE",
                        "confidentiality": "NONE",
                        "integrity": "PARTIAL",
                    },
                    "impact3": {
                        "availability": "HIGH",
                        "confidentiality": "HIGH",
                        "integrity": "HIGH",
                    },
                    "exploitability3": {
                        "attackvector": "NETWORK",
                        "attackcomplexity": "LOW",
                        "privilegesrequired": "NONE",
                        "userinteraction": "REQUIRED",
                        "scope": "CHANGED",
                    },
                    "cvss3": 9.6,
                    "impactScore3": 3.0,
                    "exploitabilityScore3": 6.6,
                    "cvss3-vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
                    "last-modified": "2018-10-12T21:29:00",
                    "references": [
                        "http://support.microsoft.com/default.aspx?scid=kb;[LN];Q231304",
                        "https://docs.microsoft.com/en-us/security-updates/securitybulletins/1999/ms99-014",
                    ],
                    "summary": "A remote attacker can disable the virus warning mechanism in Microsoft Excel 97.",
                    "vulnerable_configuration": [
                        "cpe:2.3:a:microsoft:excel:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_2000:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_95:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_98:*:gold:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_nt:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_nt:4.0:*:*:*:*:*:*:*",
                    ],
                    "vulnerable_configuration_cpe_2_2": [],
                    "vulnerable_product": [
                        "cpe:2.3:a:microsoft:excel:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_2000:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_95:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_98:*:gold:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_nt:*:*:*:*:*:*:*:*",
                        "cpe:2.3:o:microsoft:windows_nt:4.0:*:*:*:*:*:*:*",
                    ],
                },
                {
                    "Modified": "2018-10-12T21:29:00",
                    "Published": "1999-10-01T04:00:00",
                    "access": {
                        "authentication": "NONE",
                        "complexity": "LOW",
                        "vector": "LOCAL",
                    },
                    "assigner": "cve@mitre.org",
                    "cvss": 4.6,
                    "impactScore": 3.0,
                    "exploitabilityScore": 3.0,
                    "cvss-time": "2018-10-12T21:29:00",
                    "cvss-vector": "AV:L/AC:L/Au:N/C:P/I:P/A:P",
                    "cwe": "CWE-59",
                    "id": "CVE-1999-0794",
                    "impact": {
                        "availability": "PARTIAL",
                        "confidentiality": "PARTIAL",
                        "integrity": "PARTIAL",
                    },
                    "impact3": {
                        "availability": "HIGH",
                        "confidentiality": "HIGH",
                        "integrity": "HIGH",
                    },
                    "exploitability3": {
                        "attackvector": "NETWORK",
                        "attackcomplexity": "LOW",
                        "privilegesrequired": "NONE",
                        "userinteraction": "REQUIRED",
                        "scope": "CHANGED",
                    },
                    "cvss3": 9.6,
                    "impactScore3": 3.0,
                    "exploitabilityScore3": 6.6,
                    "cvss3-vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
                    "last-modified": "2018-10-12T21:29:00",
                    "references": [
                        "http://support.microsoft.com/default.aspx?scid=kb;[LN];Q241900",
                        "http://support.microsoft.com/default.aspx?scid=kb;[LN];Q241901",
                        "http://support.microsoft.com/default.aspx?scid=kb;[LN];Q241902",
                        "https://docs.microsoft.com/en-us/security-updates/securitybulletins/1999/ms99-044",
                    ],
                    "summary": "Microsoft Excel does not warn a user when a macro is present in a Symbolic Link "
                    "(SYLK) format file.",
                    "vulnerable_configuration": [
                        "cpe:2.3:a:microsoft:excel:*:*:*:*:*:*:*:*",
                        "cpe:2.3:a:microsoft:office:*:*:*:*:*:*:*:*",
                    ],
                    "vulnerable_configuration_cpe_2_2": [],
                    "vulnerable_product": ["cpe:2.3:a:microsoft:excel:*:*:*:*:*:*:*:*"],
                },
            ],
        ),
        "total": fields.Integer(
            description="Total amount of records matching this search criteria",
            example="1337",
        ),
    },
)


@api.route("/cve/<cveid>")
@api.param("cveid", "CVE number", example="CVE-2016-3333", required=True)
@api.response(400, "Error processing request", model=message)
@api.response(404, "The requested CVE is not found", model=message)
@api.response(500, "Server error", model=message)
class CveId(Resource):
    @api.marshal_with(cve_entry, skip_none=True)
    def get(self, cveid):
        """
        CVE from CVE ID

        Outputs all available information for the specified CVE (Common Vulnerability and Exposure), in JSON format.
        This information includes basic CVE information like CVSS (Common Vulnerability Scoring System),
        related CPE (Common Product Enumeration), CWE (Common Weakness Enumeration), etc as well as additional
        information (RedHat Advisories etc).
        """
        cvesp = CveHandler(
            rankinglookup=True, namelookup=True, via4lookup=True, capeclookup=True
        )
        cve = cvesp.getcve(cveid=cveid.upper())
        if cve is None:
            api.abort(404, "The requested CVE is not found")
        else:
            return cve


@api.route("/cvefor/<path:cpe>")
@api.param(
    "cpe",
    "CPE code",
    example="cpe:/o:microsoft:windows_vista:6.0:sp1:~-~home_premium~-~x64~-",
    required=True,
)
@api.param(
    "limit",
    "Limit the amount of returned documents",
    example=10,
    default=0,
    _in="query",
)
@api.response(400, "Error processing request", model=message)
@api.response(404, "No cves found", model=message)
@api.response(500, "Server error", model=message)
class CveFor(Resource):
    @api.marshal_list_with(cve_entry, skip_none=True)
    def get(self, cpe, set_limit=0):
        """
        CVE's from CPE ID

        Outputs a list of CVEs related to the product
        """
        limit = request.args.get("limit", None)

        if limit is None:
            limit = set_limit
        else:
            limit = int(limit)

        cves = qcvesForCPE(cpe, int(limit))
        if len(cves) == 0:
            api.abort(404, "No cves found")
        else:
            return cves


@api.route("/last")
@api.param(
    "limit",
    "Limit the amount of returned documents",
    example=10,
    default=30,
    _in="query",
)
@api.response(400, "Error processing request", model=message)
@api.response(404, "No cves found", model=message)
@api.response(500, "Server error", model=message)
class CveLast(Resource):
    @api.marshal_list_with(cve_last_entries, skip_none=True)
    def get(self, set_limit=30):
        """
        List last CVE's

        Outputs the last n amount of vulnerabilities. If the limit is not specified, the default of 30 is used.
        """
        limit = request.args.get("limit", None)

        if limit is None:
            limit = set_limit
        else:
            limit = int(limit)

        cvesp = CveHandler(
            rankinglookup=True, namelookup=True, via4lookup=True, capeclookup=True
        )
        cve = cvesp.get(limit=limit)

        if len(cve) == 0:
            api.abort(404, "No cves found")
        else:
            return cve


@api.route("/search/<vendor>/<path:product>")
@api.param(
    "vendor", "Vendor name", example="microsoft", required=True,
)
@api.param(
    "product", "Product name", example="excel", required=True,
)
@api.response(400, "Error processing request", model=message)
@api.response(404, "No cves found", model=message)
@api.response(500, "Server error", model=message)
class SearchCve(Resource):
    @api.marshal_with(search_entries)
    def get(self, vendor, product):
        """
        Search CVE by vendor

        When vendor and product are specified, this API call returns a list of CVEs related to the product.
        The output of the browse call can be used for this.
        """
        search = (vendor, product)

        return cvesForCPE(search, strict_vendor_product=True)


####

# /link/<key>/<value> appears to be broken; still needed?

#####
# @api.route("/link/<key>/<value>")
# @api.param(
#     "key", "The key to link CVEs on", example="msbulletin.bulletin_id", required=True,
# )
# @api.param(
#     "value", "The value for the given key", example="MS16-098", required=True,
# )
# @api.response(400, "Error processing request", model=message)
# @api.response(404, "No cves found", model=message)
# @api.response(500, "Server error", model=message)
# class SearchLinkedCve(Resource):
#     def get(self, key, value):
#         """
#         Search linked CVE
#
#         Returns all CVEs that are linked by a given key/value pair
#         """
#         key = urllib.parse.unquote_plus(key)
#         value = urllib.parse.unquote_plus(value)
#         regex = re.compile(re.escape(value), re.I)
#         data = {"cves": via4Linked(key, regex)}
#         cvss_list = [float(x["cvss"]) for x in data["cves"] if x.get("cvss")]
#         if cvss_list:
#             data["stats"] = {
#                 "maxCVSS": max(cvss_list),
#                 "minCVSS": min(cvss_list),
#                 "count": len(data["cves"]),
#             }
#         else:
#             data["stats"] = {"maxCVSS": 0, "minCVSS": 0, "count": len(data["cves"])}
#         return data
